package arabicScrabble;

import java.awt.Point;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;

import javax.swing.JLabel;

public class Player {
	String playerID;
	int score;
	int type;// 0 normal . 1 pc
	boolean turn;
	Rack rack;
	JLabel playerStatus;
	int playerNumber;
	int changedTile;
	// perms
	public LinkedList<String> words = new LinkedList<String>();
	public LinkedList<String> perms = new LinkedList<String>();
	boolean khalasfound = false;

	public Player(String playerID, Bag bag, int playerNumber, int type) {

		this.playerID = playerID;
		this.type = type;
		rack = new Rack(bag);
		
		this.playerNumber = playerNumber;
		playerStatus = new JLabel("Player  " + playerNumber + ":  " + score);
		changedTile=0;
		}

	public Rack getRack() {
		return rack;
	}

	double placeTile(int letter) {
		return 0;
	}

	public JLabel getPlayerStatus() {
		return playerStatus;
	}

	public void changeTiles(Letter L) {
		
		if(L!=null){
		rack.remove(L);
		int x = (int)(Math.random()*rack.bag.getLetters().size());
		rack.addLetter(rack.bag.removeLetter(x));
		changedTile++;
		}
	}

	public void passTurn() {

	}

	public void printRack() {

		// ill print the rack
		System.out.println("---RACK-----CONTENTS*---");
		for (int i = 0; i < this.rack.letters.size(); i++) {
			System.out.println(this.rack.letters.get(i).symbol);

		}
		System.out.println("END OF---RACK-----CONTENTS*---");

	}
	/**
	 * 
	 * @return
	 * @authoer 
	 */
	public String getRackasString() {
		// ill print the rack
		String word = "";
		for (int i = 0; i < this.rack.letters.size(); i++) {
			word += this.rack.letters.get(i).symbol;
		}
		return word;

	}

	public void printBoardLetters(Square[][] boardCell) {
		// ill print the BOARD
		System.out.println("---BOARD-----CONTENTS*---");

		for (int i = 0; i < boardCell.length; i++) {
			if (boardCell[i][0].letter != null) {
				System.out.println(boardCell[i][0].letter.symbol);
			}
			for (int j = 0; j < boardCell[i].length; j++) {
				if (boardCell[i][j].letter != null) {
					System.out.println(boardCell[i][j].letter.symbol);
				}
			}

		}
		System.out.println("END OF---BOARD-----CONTENTS*---");
	}

	// get perms
	private void checkWords(FileReader dict, String racktiles)
			throws IOException {
		BufferedReader bf = new BufferedReader(dict);
		String line = "";
		// String racktiles = getRackasString().trim();
		while ((line = bf.readLine()) != null) {
			if (hasWord(line, racktiles)) {
				this.words.add(line);
			}
		}
		bf.close();
		dict.close();
	}

	public boolean hasWord(String word, String copy) {
		for (int u = 0; u < word.length(); u++) {
			if (copy.contains(String.valueOf(word.charAt(u)))) {
				copy = copy.replaceFirst(String.valueOf(word.charAt(u)), "");
			} else {
				return false;
			}
		}
		return true;
	}

	/**
	 * returns all the valid permutaions of the rack tiles in the dictonary
	 * 
	 * @return
	 */
	public LinkedList<String> getValidPemutations(String tiles) {
		LinkedList<String> perms = new LinkedList<String>();
		try {
			checkWords(
					new FileReader(
							"C:\\Users\\Ahmed\\Desktop\\scrabble\\ArabicScrabble\\src\\arabicScrabble\\englishDict.txt"),
					tiles);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for (int i = 0; i < words.size(); i++) {
			perms.add(words.get(i));
		}
		// Sort by size desc
		Collections.sort(perms, new StringLengthComparator());
		return perms;

	}

	// end of perms
	/*
	 * see the postions wher ei can place tiles
	 */
	/**
	 * checks to see if square is !Vaccant(Letter,boarder) or vaccant
	 */
	public LinkedList<Word> analyseBoard(Square[][] boardCell) {
		LinkedList<Word> possible_words = new LinkedList<Word>();
		for (int i = 0; i < boardCell.length; i++) {
			for (int j = 0; j < boardCell[i].length; j++) {
				if (boardCell[i][j].letter != null) {
					// if vaccant form both left &&right
					if (boardCell[i][j - 1].letter == null
							&& boardCell[i][j + 1].letter == null && j > 0
							&& j < 14) {
						possible_words.add(new Word(new Point(i, j), "h", 's',
								boardCell[i][j].letter));
					}
					// if vaccant form both top &&bottom
					if (boardCell[i - 1][j].letter == null
							&& boardCell[i + 1][j].letter == null && i > 0
							&& i < 14) {
						possible_words.add(new Word(new Point(i, j), "v", 's',
								boardCell[i][j].letter));
					}
				}
			}
		}
		return possible_words;
	}

	public LinkedList<String> findwordwith(int size, char s, char letter) {
		String getTiles = getRackasString();
		words.clear();
		perms = getValidPemutations(getTiles);
		LinkedList<String> listofwords = new LinkedList<String>();
		for (int i = 0; i < perms.size(); i++) {
			if (s == 's') {// starts with l
				if (perms.get(i).charAt(0) == letter
						&& perms.get(i).length() <= size) {
					String word = perms.get(i).substring(1);
					listofwords.add(word);
					break;
				}
			}
			if (s == 'e') {// ends with l
				if (perms.get(i).charAt(perms.get(i).length() - 1) == letter
						&& perms.get(i).length() <= size) {
					String word = perms.get(i).substring(0,
							perms.get(i).length() - 1);
					listofwords.add(word);
					break;
				}
			}
		}
		return listofwords;

	}

	public void findPermthat(Word word, Square[][] boardCell) {
		boolean found = false;
		boolean stoploo = false;
		// case H
		if (word.orientaion.equals("h") && !found) {
			LinkedList<String> listofPCwords = new LinkedList<String>();
			LinkedList<String> listofPCwords2 = new LinkedList<String>();
			int size = 0;
			// get the size of the word to be placed
			for (int i = word.position.y + 1; i < 14 && !stoploo; i++) {
				// H---> and the verical is emptyu from both sides aw completes
				// a word
				if (boardCell[word.position.x][i].letter == null
						&& boardCell[word.position.x][i + 1].letter == null
						&& i < 15
						&& boardCell[word.position.x + 1][i].letter == null
						&& boardCell[word.position.x - 1][i].letter == null) {
					size++;
				} else {
					stoploo = true;
					break;
				}

			}
			listofPCwords = findwordwith(size, 's', word.l.symbol);
			if (listofPCwords.size() == 0) {// not found ie)pass
				System.out.println("PASS");
			} else {
				// we found words
				found = true;
				khalasfound = true;
				System.out.println("found  H  --> " + listofPCwords.getFirst()
						+ " on word " + word.l.symbol);
				// place em on board & remove from rack
				String word2place = listofPCwords.getFirst().trim();
				for (int i = 0; i < word2place.length(); i++) {
					for (int j = 0; j < this.rack.letters.size(); j++) {
						if (this.rack.letters.get(j).symbol == word2place
								.charAt(i)) {
							// add tile to board
							Letter l = this.rack.letters.get(j);
							// System.out.println("added to BOARD -- "
							// + this.rack.letters.get(j).symbol);
							//
							boardCell[word.position.x][word.position.y + 1 + i]
									.add(l);
							this.rack.letters.remove(l);
							break;
						}
					}
				}
				// end of placing & removing from rack

			}
			// handle the case , when the letter ends with L
			if (!found) {
				size = 0;
				stoploo = false;
				// get the size of the word to be placed
				for (int i = word.position.y - 1; i > 0 && !stoploo; i--) {
					if (boardCell[word.position.x][i].letter == null
							&& boardCell[word.position.x][i - 1].letter == null
							&& i - 1 > 0) {
						if (boardCell[word.position.x + 1][i].letter == null
								&& boardCell[word.position.x - 1][i].letter == null) {
							size++;
						} else {
							stoploo = true;
							break;
						}
					}
				}
				// find a word that starts with L & of lenght <=size
				listofPCwords2 = findwordwith(size, 'e', word.l.symbol);
				if (listofPCwords2.size() == 0) {// not found ie)pass
					System.out.println("PASS");
				} else {
					// we found words
					found = true;
					khalasfound = true;
					System.out.println("found    <---H "
							+ listofPCwords2.getFirst() + " on word "
							+ word.l.symbol);
					// place em on board & remove from rack
					String word2place = listofPCwords2.getFirst();
					for (int i = 0; i < word2place.length(); i++) {
						// get the letter obj form the rack
						for (int j = 0; j < this.rack.letters.size(); j++) {
							if (this.rack.letters.get(j).symbol == word2place
									.charAt(i)) {
								// add tile to board
								// System.out.println("added to BOARD -- "
								// + this.rack.letters.get(j).symbol);
								Letter l = this.rack.letters.get(j);
								boardCell[word.position.x][word.position.y
										- word2place.length() + i].add(l);
								this.rack.letters.remove(l);
								break;
							}
						}
					}
					// end of placing & removing from rack
				}
			}
		}
		// end of Case H
		// case V
		stoploo = false;
		int size = 0;
		if (word.orientaion.equals("v") && !found) {
			LinkedList<String> listofPCwords = new LinkedList<String>();

			for (int i = word.position.x + 1; i < 14 && !stoploo; i++) {
				if (boardCell[i][word.position.y].letter == null
						&& boardCell[i + 1][word.position.y].letter == null
						&& i < 15
						&& boardCell[i][word.position.y + 1].letter == null
						&& boardCell[i][word.position.y - 1].letter == null

				) {
					size++;
				} else {
					stoploo = true;
					break;
				}

			}

			listofPCwords = findwordwith(size, 's', word.l.symbol);
			if (listofPCwords.size() == 0) {// not found ie)pass
				System.out.println("PASS");
			} else {
				// we found words
				found = true;
				khalasfound = true;
				System.out.println("found  V  --> " + listofPCwords.getFirst()
						+ " on word " + word.l.symbol);
				// place em on board & remove from rack
				String word2place = listofPCwords.getFirst().trim();
				for (int i = 0; i < word2place.length(); i++) {
					for (int j = 0; j < this.rack.letters.size(); j++) {
						if (this.rack.letters.get(j).symbol == word2place
								.charAt(i)) {
							// add tile to board
							Letter l = this.rack.letters.get(j);
							boardCell[word.position.x + 1 + i][word.position.y]
									.add(l);
							this.rack.letters.remove(l);
							break;
						}
					}
				}
				// end of placing & removing from rack
			}
		}
		// end of Case V
	}

	public Square[][] pcPlay(Square[][] boardCell)
			throws FileNotFoundException, IOException {
		khalasfound = false;
		LinkedList<Word> possible_places_tiles = analyseBoard(boardCell);
		for (int i = 0; i < possible_places_tiles.size(); i++) {
			if (!khalasfound) {
				findPermthat(possible_places_tiles.get(i), boardCell);
			}
		}
		// if not found (ie->pass)
		// change Tiles
		if (!khalasfound) {
			// changeTiles
		}
		return boardCell;
	}
}
